filechooser: Add gtk_file_chooser_get_filters
authorMatthias Clasen <mclasen@redhat.com>
Sat, 4 Jul 2020 16:15:47 +0000 (12:15 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 6 Jul 2020 14:36:35 +0000 (10:36 -0400)
Replace gtk_file_chooser_list_filters with a new
api that returns a list model.

Update all callers.

docs/reference/gtk/gtk4-sections.txt
gtk/gtkfilechooser.c
gtk/gtkfilechooser.h
gtk/gtkfilechoosernativeportal.c
gtk/gtkfilechoosernativequartz.c
gtk/gtkfilechoosernativewin32.c
gtk/gtkfilechooserprivate.h
gtk/gtkfilechooserutils.c
gtk/gtkfilechooserwidget.c
tests/testgtk.c

index 5edc9317719c598e6453a6bab5e36a983e8885e6..b6e9bc06f37c909d69182015905dc856e5142190 100644 (file)
@@ -1310,7 +1310,7 @@ gtk_file_chooser_get_current_folder
 <SUBSECTION>
 gtk_file_chooser_add_filter
 gtk_file_chooser_remove_filter
-gtk_file_chooser_list_filters
+gtk_file_chooser_get_filters
 gtk_file_chooser_set_filter
 gtk_file_chooser_get_filter
 <SUBSECTION>
index 985a18a1caca4840e62fc99d48665e1bf8076d5e..93dbf91549457a22740344b4de2f5ccb5fbf88c5 100644 (file)
@@ -682,23 +682,24 @@ gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
 }
 
 /**
- * gtk_file_chooser_list_filters:
+ * gtk_file_chooser_get_filters:
  * @chooser: a #GtkFileChooser
  * 
- * Lists the current set of user-selectable filters; see
+ * Gets the current set of user-selectable filters, as a list model; see
  * gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
  *
- * Returns: (element-type GtkFileFilter) (transfer container): a
- *  #GSList containing the current set of user selectable filters. The
- *  contents of the list are owned by GTK+, but you must free the list
- *  itself with g_slist_free() when you are done with it.
+ * You should not modify the returned list model. Future changes to
+ * @chooser may or may not affect the returned model.
+ *
+ * Returns: (transfer full): a #GListModel containing the current set
+ *     of user-selectable filters.
  **/
-GSList *
-gtk_file_chooser_list_filters  (GtkFileChooser *chooser)
+GListModel *
+gtk_file_chooser_get_filters (GtkFileChooser *chooser)
 {
   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
 
-  return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
+  return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_filters (chooser);
 }
 
 /**
index 2aff129c5df3b32e56d8a9c9ec9fc21b767fb181..1f3381b993a5ebb0b91ec8e5909c102eeeb01018 100644 (file)
@@ -145,18 +145,18 @@ GFile *  gtk_file_chooser_get_current_folder      (GtkFileChooser  *chooser);
  */
 GDK_AVAILABLE_IN_ALL
 void    gtk_file_chooser_add_filter    (GtkFileChooser *chooser,
-                                       GtkFileFilter  *filter);
+                                        GtkFileFilter  *filter);
 GDK_AVAILABLE_IN_ALL
 void    gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
-                                       GtkFileFilter  *filter);
+                                        GtkFileFilter  *filter);
 GDK_AVAILABLE_IN_ALL
-GSList *gtk_file_chooser_list_filters  (GtkFileChooser *chooser);
+GListModel *gtk_file_chooser_get_filters  (GtkFileChooser *chooser);
 
 /* Current filter
  */
 GDK_AVAILABLE_IN_ALL
 void           gtk_file_chooser_set_filter (GtkFileChooser *chooser,
-                                           GtkFileFilter  *filter);
+                                            GtkFileFilter  *filter);
 GDK_AVAILABLE_IN_ALL
 GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
 
index db992b9b5b541d7b53b33b3bdd66325c16e4fd79..d14a28cb349b7a80b34876cf06af6ac2e9e31088 100644 (file)
@@ -126,7 +126,7 @@ response_cb (GDBusConnection  *connection,
   if (current_filter)
     {
       GtkFileFilter *filter = gtk_file_filter_new_from_gvariant (current_filter);
-      const gchar *current_filter_name = gtk_file_filter_get_name (filter);
+      const char *current_filter_name = gtk_file_filter_get_name (filter);
 
       /* Try to find  the given filter in the list of filters.
        * Since filters are compared by pointer value, using the passed
@@ -137,18 +137,24 @@ response_cb (GDBusConnection  *connection,
        * If there is no match, just set the filter as it was retrieved.
        */
       GtkFileFilter *filter_to_select = filter;
-      GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
-      for (GSList *l = filters; l; l = l->next)
+      GListModel *filters;
+      guint j, n;
+
+      filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
+      n = g_list_model_get_n_items (filters);
+      for (j = 0; j < n; j++)
         {
-          GtkFileFilter *f = l->data;
+          GtkFileFilter *f = g_list_model_get_item (filters, j);
           if (g_strcmp0 (gtk_file_filter_get_name (f), current_filter_name) == 0)
             {
               filter_to_select = f;
               break;
             }
+          g_object_unref (f);
         }
-      g_slist_free (filters);
+      g_object_unref (filters);
       gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self), filter_to_select);
+      g_object_unref (filter_to_select);
     }
 
   g_slist_free_full (self->custom_files, g_object_unref);
@@ -264,17 +270,20 @@ open_file_msg_cb (GObject *source_object,
 static GVariant *
 get_filters (GtkFileChooser *self)
 {
-  GSList *list, *l;
+  GListModel *filters;
+  guint n, i;
   GVariantBuilder builder;
 
   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa(us))"));
-  list = gtk_file_chooser_list_filters (self);
-  for (l = list; l; l = l->next)
+  filters = gtk_file_chooser_get_filters (self);
+  n = g_list_model_get_n_items (filters);
+  for (i = 0; i < n; i++)
     {
-      GtkFileFilter *filter = l->data;
+      GtkFileFilter *filter = g_list_model_get_item (filters, i);
       g_variant_builder_add (&builder, "@(sa(us))", gtk_file_filter_to_gvariant (filter));
+      g_object_unref (filter);
     }
-  g_slist_free (list);
+  g_object_unref (filters);
 
   return g_variant_builder_end (&builder);
 }
index 6ce0e936f7136466fab29464c628fd6b234e54cf..d7cf4113a47d7e194c533380d7eeff12a749b107 100644 (file)
@@ -99,9 +99,10 @@ typedef struct {
   else
     [data->panel setAllowedFileTypes:filter];
 
-  GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
-  data->self->current_filter = g_slist_nth_data (filters, selected_index);
-  g_slist_free (filters);
+  GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
+  data->self->current_filter = g_list_model_get_item (filters, selected_index);
+  g_object_unref (data->self->current_filter);
+  g_object_unref (filters);
   g_object_notify (G_OBJECT (data->self), "filter");
 }
 @end
@@ -307,13 +308,28 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
 
       if (data->self->current_filter)
         {
-          GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
-         gint current_filter_index = g_slist_index (filters, data->self->current_filter);
-         g_slist_free (filters);
+          GListModel *filters;
+          guint i, n;
+          guint current_filter_index = GTK_INVALID_LIST_POSITION;
 
-         if (current_filter_index >= 0)
+          filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
+          n = g_list_model_get_n_items (filters);
+          for (i = 0; i < n; i++)
+            {
+              gpointer item = g_list_model_get_item (filters, i);
+              if (item == data->self->current_filter)
+                {
+                  g_object_unref (item);
+                  current_filter_index = i;
+                  break;
+                }
+              g_object_unref (item);
+            }
+          g_object_unref (filters);
+
+          if (current_filter_index != GTK_INVALID_LIST_POSITION)
             [data->filter_combo_box selectItemAtIndex:current_filter_index];
-         else
+          else
             [data->filter_combo_box selectItemAtIndex:0];
         }
       else
@@ -437,15 +453,15 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
   GtkWindow *transient_for;
   GtkFileChooserAction action;
 
-  GSList *filters, *l;
-  int n_filters, i;
+  GListModel *filters;
+  guint n_filters, i;
   char *message = NULL;
 
   data = g_new0 (FileChooserQuartzData, 1);
 
   // examine filters!
-  filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
-  n_filters = g_slist_length (filters);
+  filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
+  n_filters = g_list_model_get_n_items (filters);
   if (n_filters > 0)
     {
       data->filters = [NSMutableArray arrayWithCapacity:n_filters];
@@ -453,13 +469,17 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
       data->filter_names = [NSMutableArray arrayWithCapacity:n_filters];
       [data->filter_names retain];
 
-      for (l = filters, i = 0; l != NULL; l = l->next, i++)
+      for (i = 0; i < n; i++)
         {
-          if (!file_filter_to_quartz (l->data, data->filters, data->filter_names))
+          GtkFileFilter *filter = g_list_model_get_item (filters, i);
+          if (!file_filter_to_quartz (filter, data->filters, data->filter_names))
             {
               filechooser_quartz_data_free (data);
+              g_object_unref (filter);
+              g_object_unref (filters);
               return FALSE;
             }
+          g_object_unref (filter);
         }
       self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
     }
@@ -467,6 +487,8 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
     {
       self->current_filter = NULL;
     }
+  g_object_unref (filters);
+
   self->mode_data = data;
   data->self = g_object_ref (self);
 
index 026fcd862b5e6c2f8d52ac25bf221c6cd2ded38a..722f324ae871ba714cd9ebbb4ffea70c7a7811ea 100644 (file)
@@ -244,9 +244,11 @@ ifiledialogevents_OnTypeChange (IFileDialogEvents * self,
       return S_OK;
     }
   fileType--; // fileTypeIndex starts at 1 
-  GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (events->data->self));
-  events->data->self->current_filter = g_slist_nth_data (filters, fileType);
-  g_slist_free (filters);
+  GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (events->data->self));
+  GtkFileFilter *filter = g_list_model_get_item (filters, fileType);
+  events->data->self->current_filter = filter;
+  g_object_unref (filter);
+  g_object_unref (filters);
   g_object_notify (G_OBJECT (events->data->self), "filter");
   return S_OK;
 }
@@ -591,9 +593,24 @@ filechooser_win32_thread (gpointer _data)
 
       if (data->self->current_filter)
         {
-          GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
-         gint current_filter_index = g_slist_index (filters, data->self->current_filter);
-         g_slist_free (filters);
+          GListModel *filters;
+          guint n_items, i;
+          guint current_filter_index = GTK_INVALID_LIST_POSITION;
+
+          filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
+          n_items = g_list_model_get_n_items (filters);
+          for (i = 0; i < n_items; i++)
+            {
+              gpointer item = g_list_model_get_item (filters, i);
+              if (item == data->self->current_filter)
+                {
+                  current_filter_index = i;
+                  g_object_unref (item);
+                  break;
+                }
+              g_object_unref (item);
+            }
+         g_object_unref (filters);
 
          if (current_filter_index >= 0)
            hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
@@ -864,21 +881,24 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
   FilechooserWin32ThreadData *data;
   GtkWindow *transient_for;
   GtkFileChooserAction action;
-  GSList *filters, *l;
-  int n_filters, i;
+  GListModel *filters;
+  guint n_filters, i;
 
   data = g_new0 (FilechooserWin32ThreadData, 1);
 
-  filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
-  n_filters = g_slist_length (filters);
+  filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
+  n_filters = g_list_model_get_n_items (filters);
   if (n_filters > 0)
     {
       data->filters = g_new0 (COMDLG_FILTERSPEC, n_filters + 1);
 
-      for (l = filters, i = 0; l != NULL; l = l->next, i++)
+      for (i = 0; i < n_filters; i++)
         {
-          if (!file_filter_to_win32 (l->data, &data->filters[i]))
+          GtkFileFilter *filter = g_list_model_get_item (filters, i);
+          if (!file_filter_to_win32 (filter, &data->filters[i]))
             {
+              g_object_unref (filter);
+              g_object_unref (filters);
               filechooser_win32_thread_data_free (data);
               return FALSE;
             }
@@ -889,6 +909,7 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
     {
       self->current_filter = NULL;
     }
+  g_object_unref (filters);
 
   self->mode_data = data;
   data->self = g_object_ref (self);
index 06a49dea03acae677e28bfb7b381f71232fd5814..d0f2b5391065c65eb16c78ab97ef17b110e4f0bf 100644 (file)
@@ -58,33 +58,33 @@ struct _GtkFileChooserIface
 
   /* Methods
    */
-  gboolean       (*set_current_folder)            (GtkFileChooser    *chooser,
-                                           GFile             *file,
-                                           GError           **error);
-  GFile *        (*get_current_folder)            (GtkFileChooser    *chooser);
-  void           (*set_current_name)              (GtkFileChooser    *chooser,
-                                           const gchar       *name);
+  gboolean       (*set_current_folder)     (GtkFileChooser    *chooser,
+                                            GFile             *file,
+                                            GError           **error);
+  GFile *        (*get_current_folder)     (GtkFileChooser    *chooser);
+  void           (*set_current_name)       (GtkFileChooser    *chooser,
+                                            const gchar       *name);
   gchar *        (*get_current_name)       (GtkFileChooser    *chooser);
-  gboolean       (*select_file)                   (GtkFileChooser    *chooser,
-                                           GFile             *file,
-                                           GError           **error);
-  void           (*unselect_file)                 (GtkFileChooser    *chooser,
-                                           GFile             *file);
-  void           (*select_all)                    (GtkFileChooser    *chooser);
-  void           (*unselect_all)                  (GtkFileChooser    *chooser);
-  GSList *       (*get_files)                     (GtkFileChooser    *chooser);
-  GtkFileSystem *(*get_file_system)               (GtkFileChooser    *chooser);
-  void           (*add_filter)                    (GtkFileChooser    *chooser,
-                                           GtkFileFilter     *filter);
-  void           (*remove_filter)                 (GtkFileChooser    *chooser,
-                                           GtkFileFilter     *filter);
-  GSList *       (*list_filters)                  (GtkFileChooser    *chooser);
+  gboolean       (*select_file)            (GtkFileChooser    *chooser,
+                                            GFile             *file,
+                                            GError           **error);
+  void           (*unselect_file)          (GtkFileChooser    *chooser,
+                                            GFile             *file);
+  void           (*select_all)             (GtkFileChooser    *chooser);
+  void           (*unselect_all)           (GtkFileChooser    *chooser);
+  GSList *       (*get_files)              (GtkFileChooser    *chooser);
+  GtkFileSystem *(*get_file_system)        (GtkFileChooser    *chooser);
+  void           (*add_filter)             (GtkFileChooser    *chooser,
+                                            GtkFileFilter     *filter);
+  void           (*remove_filter)          (GtkFileChooser    *chooser,
+                                            GtkFileFilter     *filter);
+  GListModel *   (*get_filters)            (GtkFileChooser    *chooser);
   gboolean       (*add_shortcut_folder)    (GtkFileChooser    *chooser,
-                                           GFile             *file,
-                                           GError           **error);
+                                            GFile             *file,
+                                            GError           **error);
   gboolean       (*remove_shortcut_folder) (GtkFileChooser    *chooser,
-                                           GFile             *file,
-                                           GError           **error);
+                                            GFile             *file,
+                                            GError           **error);
   GSList *       (*list_shortcut_folders)  (GtkFileChooser    *chooser);
 
   /* Signals
index afa166056e63ef1626fa1f2da087481d91ce4d94..71713a49ff17d12e2c9096a9b596e33e6d9bdd7a 100644 (file)
@@ -45,7 +45,7 @@ static void           delegate_add_filter             (GtkFileChooser    *choose
                                                       GtkFileFilter     *filter);
 static void           delegate_remove_filter          (GtkFileChooser    *chooser,
                                                       GtkFileFilter     *filter);
-static GSList *       delegate_list_filters           (GtkFileChooser    *chooser);
+static GListModel *   delegate_get_filters            (GtkFileChooser    *chooser);
 static gboolean       delegate_add_shortcut_folder    (GtkFileChooser    *chooser,
                                                       GFile             *file,
                                                       GError           **error);
@@ -131,7 +131,7 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
   iface->get_file_system = delegate_get_file_system;
   iface->add_filter = delegate_add_filter;
   iface->remove_filter = delegate_remove_filter;
-  iface->list_filters = delegate_list_filters;
+  iface->get_filters = delegate_get_filters;
   iface->add_shortcut_folder = delegate_add_shortcut_folder;
   iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
   iface->list_shortcut_folders = delegate_list_shortcut_folders;
@@ -241,10 +241,10 @@ delegate_remove_filter (GtkFileChooser *chooser,
   gtk_file_chooser_remove_filter (get_delegate (chooser), filter);
 }
 
-static GSList *
-delegate_list_filters (GtkFileChooser *chooser)
+static GListModel *
+delegate_get_filters (GtkFileChooser *chooser)
 {
-  return gtk_file_chooser_list_filters (get_delegate (chooser));
+  return gtk_file_chooser_get_filters (get_delegate (chooser));
 }
 
 static gboolean
index 48d31858689040dd341b92e0c51cf5e75d162a51..1c2d2619ed222ff941d2a0625767647433f22e0b 100644 (file)
@@ -485,7 +485,7 @@ static void           gtk_file_chooser_widget_add_filter                   (GtkF
                                                                             GtkFileFilter     *filter);
 static void           gtk_file_chooser_widget_remove_filter                (GtkFileChooser    *chooser,
                                                                             GtkFileFilter     *filter);
-static GSList *       gtk_file_chooser_widget_list_filters                 (GtkFileChooser    *chooser);
+static GListModel *   gtk_file_chooser_widget_get_filters                  (GtkFileChooser    *chooser);
 static gboolean       gtk_file_chooser_widget_add_shortcut_folder    (GtkFileChooser    *chooser,
                                                                        GFile             *file,
                                                                        GError           **error);
@@ -619,7 +619,7 @@ gtk_file_chooser_widget_iface_init (GtkFileChooserIface *iface)
   iface->get_current_name = gtk_file_chooser_widget_get_current_name;
   iface->add_filter = gtk_file_chooser_widget_add_filter;
   iface->remove_filter = gtk_file_chooser_widget_remove_filter;
-  iface->list_filters = gtk_file_chooser_widget_list_filters;
+  iface->get_filters = gtk_file_chooser_widget_get_filters;
   iface->add_shortcut_folder = gtk_file_chooser_widget_add_shortcut_folder;
   iface->remove_shortcut_folder = gtk_file_chooser_widget_remove_shortcut_folder;
   iface->list_shortcut_folders = gtk_file_chooser_widget_list_shortcut_folders;
@@ -5599,23 +5599,12 @@ gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
     show_filters (impl, FALSE);
 }
 
-static GSList *
-gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser)
+static GListModel *
+gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser)
 {
   GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
-  GSList *filters;
-  guint i;
-
-  filters = NULL;
-
-  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (impl->filters)); i++)
-    {
-      GtkFileFilter *filter = g_list_model_get_item (G_LIST_MODEL (impl->filters), i);
-      filters = g_slist_append (filters, filter);
-      g_object_unref (filter);
-    }
 
-  return filters;
+  return G_LIST_MODEL (g_object_ref (impl->filters));
 }
 
 static gboolean
index 10507a3f3a59f8e66deb2384b855b4471c736932..50db5c8111743e406e929a561f6ff17b7b7d532e 100644 (file)
@@ -5672,15 +5672,19 @@ native_filter_changed (GtkWidget *combo,
                        GtkFileChooserNative *native)
 {
   int i;
-  GSList *filters, *l;
+  GListModel *filters;
   GtkFileFilter *filter;
 
   i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
 
-  filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (native));
-  for (l = filters; l != NULL; l = l->next)
-    gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), l->data);
-  g_slist_free (filters);
+  filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (native));
+  while (g_list_model_get_n_items (filters) > 0)
+    {
+      GtkFileFilter *f = g_list_model_get_item (filters, 0);
+      gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), f);
+      g_object_unref (f);
+    }
+  g_object_unref (filters);
 
   switch (i)
     {